package com.liuyjy2.encryptDecrypt;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @Author liuyjy
 * @Date 2025/2/20 12:48
 * @Description: 监控增强：
 **/
@Slf4j
@Aspect
@Component
public class BaseEncryptDecryptAspect {
    private final ObjectMapper objectMapper;

    public BaseEncryptDecryptAspect(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.objectMapper.setAnnotationIntrospector(new CryptoInterceptor());
    }

    @Around("@annotation(com.liuyjy2.encryptDecrypt.EncryptDecrypt)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args = joinPoint.getArgs();
        args = Arrays.stream(args)
                .map(this::processArgument)
                .toArray();

        Object result = joinPoint.proceed(args);

        return processResult(result);
    }

    private Object processArgument(Object arg) {
        if (arg != null && isEncryptable(arg.getClass())) {
            try {
                return objectMapper.writeValueAsString(arg);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        return arg;
    }

    private Object processResult(Object result) throws Exception {
        if (result != null && isEncryptable(result.getClass())) {
            return objectMapper.readValue(result.toString(), result.getClass());
        }
        return result;
    }

    private boolean isEncryptable(Class<?> clazz) {
        return clazz.isAnnotationPresent(EncryptDecrypt.class);
    }
}
